/**
 * 
 */
package com.hexacta.hrs.web.struts.actions.feedbacks;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import com.hexacta.hrs.domain.feedback.FeedbackPeriodResumeByRole;
import com.hexacta.hrs.domain.feedback.Period;
import com.hexacta.hrs.services.feedbacks.FeedbackPeriodService;
import com.hexacta.hrs.services.feedbacks.PeriodService;
import com.opensymphony.xwork2.ActionSupport;

import edu.emory.mathcs.backport.java.util.Arrays;

/**
 * Action que maneja el cierre y apertura de los feedbacks, diferenciados por banda.
 * 
 * @author epereyra
 * 
 */
public class ManageFeedbacksRolesAction extends ActionSupport {

	private static final long serialVersionUID = -8669310837487483759L;

	private FeedbackPeriodService feedbackPeriodService;
	
	private PeriodService periodService;

	private String[] checked;

	private String[] oldChecked;
	
	private List<FeedbackPeriodResumeByRole> feedbackPeriodResumeByRolesList;
	
	private String periodId;

	public FeedbackPeriodService getFeedbackPeriodService() {
		return feedbackPeriodService;
	}

	public void setFeedbackPeriodService(
			FeedbackPeriodService feedbackPeriodService) {
		this.feedbackPeriodService = feedbackPeriodService;
	}
	
	public PeriodService getPeriodService() {
		return periodService;
	}

	public void setPeriodService(PeriodService periodService) {
		this.periodService = periodService;
	}

	public String[] getChecked() {
		return checked;
	}

	public void setChecked(String[] checked) {
		this.checked = checked;
	}

	public String[] getOldChecked() {
		return oldChecked;
	}

	public void setOldChecked(String[] oldChecked) {
		this.oldChecked = oldChecked;
	}

	public List<FeedbackPeriodResumeByRole> getFeedbackPeriodResumeByRolesList() {
		return this.feedbackPeriodService.getAllFeedbackPeriodResumesByRole(this.getPeriodId());
	}

	public void setFeedbackPeriodResumeByRolesList(List<FeedbackPeriodResumeByRole> feedbackPeriodResumeByRolesList) {
		this.feedbackPeriodResumeByRolesList = feedbackPeriodResumeByRolesList;
	}
	
	public String getPeriodId() {
		return periodId;
	}

	public void setPeriodId(String period) {
		this.periodId = period;
	}

	@Override
	public String execute() throws Exception {
		return SUCCESS;
	}
	/**
	 * Revisa que roles fueron seleccionados y los cierra, en caso contrario, los que fueron deseleccionados los abre.
	 * 
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public String openAndClosePeriod() throws Exception {
		
		List<String> fromPage = new ArrayList<String>();
		try {
			fromPage = Arrays.asList(checked);;
		} catch (Exception e) {
		}
		List<String> fromBase = new ArrayList<String>();
		this.feedbackPeriodResumeByRolesList = getFeedbackPeriodResumeByRolesList();
		for (FeedbackPeriodResumeByRole feedbackRole : feedbackPeriodResumeByRolesList) {
			if (feedbackRole.isClosed()){
				fromBase.add(feedbackRole.getCode());
			}
		}
		Collection<String> disjunction = CollectionUtils.disjunction(fromBase, fromPage);
		int total = feedbackPeriodResumeByRolesList.size();
		int totalChecked = fromBase.size();
		
		Period period = periodService.getPeriodByYear(getPeriodId());

		for (FeedbackPeriodResumeByRole feedbackRole : feedbackPeriodResumeByRolesList) {
			for (String idOpenPeriod : disjunction) {
				if (feedbackRole.getCode().equals(idOpenPeriod)&& !feedbackRole.isClosed()){
					this.feedbackPeriodService.updateClosedFeedbackPeriod(this.feedbackPeriodService.
						findOpenFeedbacks(feedbackRole.getCode(), period), true);
					feedbackRole.setClosed(true);
					totalChecked++;
				}else if (feedbackRole.getCode().equals(idOpenPeriod)&& feedbackRole.isClosed()){
					this.feedbackPeriodService.updateClosedFeedbackPeriod(this.feedbackPeriodService.
						findClosedPeriods(feedbackRole.getCode(), period), false);
					feedbackRole.setClosed(false);
					totalChecked--;
				}
			}
		}
	
		if ((total-totalChecked)==0 ){
			periodService.closePeriod(period);
		}else{
			if(period.isClosed()==true){
				periodService.openPeriod(period);
			}
		}
		return SUCCESS;
	}
	/**
	 * Cierra o abre todas las bandas, dependiendo del estado en que se encuentren.
	 * 
	 * En caso de haber al menos un rol abierto los cierra, en caso de estar todos cerrados los abre.
	 * 
	 * @return
	 * @throws Exception
	 */
	public String closeAllPeriods() throws Exception {
		boolean atLeastOne = false;
		Period period = periodService.getPeriodByYear(getPeriodId());
		
		for (FeedbackPeriodResumeByRole feedbackRole : getFeedbackPeriodResumeByRolesList()) {
			if(!feedbackRole.isClosed()){
				this.feedbackPeriodService.
					updateClosedFeedbackPeriod(this.feedbackPeriodService.
							findOpenFeedbacks(feedbackRole.getCode(), period), true);
				atLeastOne = true;
				}
			}
		if(atLeastOne){
			periodService.closePeriod(getPeriodId());
		}
		if (!atLeastOne){
			for (FeedbackPeriodResumeByRole feedbackRole : getFeedbackPeriodResumeByRolesList()) {
				if(feedbackRole.isClosed()){
					this.feedbackPeriodService.updateClosedFeedbackPeriod(this.feedbackPeriodService.
							findClosedPeriods(feedbackRole.getCode(), period), false);
					}
				}
			periodService.openPeriod(getPeriodId());
		}
		return SUCCESS;
	}
	
	public boolean checkForOpenedPeriod(){
		Period period = periodService.getPeriodByYear(getPeriodId());
		if ((periodService.getOpenPeriod() != null)	&& (periodService.getOpenPeriod() != period)) {
			return true;
		}else {
			return false;
		}
		
	}

}
